package mysql

import (
	"gorm.io/gorm"
	"wms/models"
)

// GetMenuBasicByIdentity 获取菜单通过 identity
func GetMenuBasicByIdentity(identity string) *gorm.DB {
	tx := DB.Model(new(models.MenuBasic)).Select("*").Where("identity = ?", identity)
	return tx
}

// GetMenuParentIdByIdentity 获取菜单的 parent_id 通过 Identity
func GetMenuParentIdByIdentity(identity string) *gorm.DB {
	tx := GetMenuBasicByIdentity(identity).Select("parent_id")
	return tx
}

// GetMenuIdByIdentity 获取菜单的原生 id 通过 Identity
func GetMenuIdByIdentity(identity string) *gorm.DB {
	tx := GetMenuBasicByIdentity(identity).Select("id")
	return tx
}

// GetMenusByIdentitys 获取菜单集合通过 identitys
func GetMenusByIdentitys(identitys []string) *gorm.DB {
	tx := DB.Model(new(models.MenuBasic)).Select("*").
		Where("identity IN ?", identitys)
	return tx
}

// GetMenuIdsByIdentitys 获取菜单集合的原生 id, identity 通过 identitys
func GetMenuIdsByIdentitys(identitys []string) *gorm.DB {
	tx := GetMenusByIdentitys(identitys).Select("id, identity")
	return tx
}

// GetMenuIdsCURDsByIdentitys 获取菜单集合的原生 id,curd 通过 identitys
func GetMenuIdsCURDsByIdentitys(identitys []string) *gorm.DB {
	tx := GetMenusByIdentitys(identitys).Select("rm.id, menu_basic.identity, rm.crud").
		Joins("LEFT JOIN role_menu rm on rm.menu_id = menu_basic.id")
	return tx
}

// GetMenusByParentId 获取菜单集合通过 parent_id
func GetMenusByParentId(parent_id uint) *gorm.DB {
	tx := DB.Model(new(models.MenuBasic)).Select("*").
		Where("parent_id = ?", parent_id)
	return tx
}

// GetMenuIdentitysByParentId 获取菜单集合的 identitys 通过 parent_id
func GetMenuIdentitysByParentId(parent_id uint) *gorm.DB {
	tx := GetMenusByParentId(parent_id).Select("identity")
	return tx
}

// GetMenuIdentitysWithHasChildrenByIdentitys 获取有子级菜单的菜单集合(而不是菜单level是目录)的 identitys 通过传入的菜单唯一标识集合 identitys
func GetMenuIdentitysWithHasChildrenByIdentitys(identitys []string) *gorm.DB {
	subQuery := DB.Table("menu_basic").Select("parent_id").Where("parent_id IS NOT NULL")
	tx := DB.Model(new(models.MenuBasic)).Select("identity").
		Where("parent_id = 0 and identity IN ?", identitys).
		Where("identity IN (?)", subQuery)
	/*
		 	可能有点低效，之后有想法再回头修改
			select identity
			from menu_basic
			where parent_id = 0
				and identity in identitys
				and identity in (
					select parent_id
					from menu_basic
				)
	*/
	return tx
}

// InsertOneMenu 插入一个菜单项
func InsertOneMenu(mb *models.MenuBasic) error {
	err := DB.Create(mb).Error
	return err
}

// UpdateOneMenu 更新一个菜单项
func UpdateOneMenu(mb *models.MenuBasic) error {
	err := DB.Model(new(models.MenuBasic)).Where("identity = ?", mb.Identity).Updates(map[string]interface{}{
		"parent_id": mb.ParentId,
		"name":      mb.Name,
		"web_icon":  mb.WebIcon,
		"path":      mb.Path,
		"sort":      mb.Sort,
		"level":     mb.Level,
	}).Error
	return err
}

// TransactionDeleteMenu 事务删除菜单，并删除所有依赖表项。menu_basic, role_menu, function_basic, role_function 都会执行删除
func TransactionDeleteMenu(identitys []string) error {
	err := DB.Transaction(func(tx *gorm.DB) error {
		// 1. 通过 identities 获取到所有菜单原生 id
		menuIds := make([]uint, len(identitys))
		err1 := tx.Model(new(models.MenuBasic)).Select("id").
			Where("identity IN ?", identitys).Scan(&menuIds).Error
		if err1 != nil {
			return err1
		}
		// 2. 删除 menu_basic 的数据项
		err2 := tx.Where("identity IN ?", identitys).Delete(new(models.MenuBasic)).Error
		if err2 != nil {
			return err2
		}
		// 3. 通过 menu_ids 获取到所有的 function_id
		funcIds := make([]uint, 0)
		err3 := tx.Model(new(models.FunctionBasic)).Select("id").
			Where("menu_id IN ?", menuIds).Scan(&funcIds).Error
		if err3 != nil {
			return err3
		}
		// 4. 通过 function_id 删除所有的 role_function
		err4 := tx.Where("function_id IN ?", funcIds).Delete(new(models.RoleFunction)).Error
		if err4 != nil {
			return err4
		}
		// 5. 通过 menu_ids 删除所有的 function_basic, role_menu,
		err5 := tx.Where("menu_id IN ?", menuIds).Delete(new(models.FunctionBasic)).Error
		if err5 != nil {
			return err5
		}
		err6 := tx.Where("menu_id IN ?", menuIds).Delete(new(models.RoleMenu)).Error
		if err6 != nil {
			return err6
		}
		return nil
	})

	return err
}
